/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including but not limited to the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to provide persons with access to the Software
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGE OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

import React, { useRef, useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { RootState, AppDispatch } from '../../store';
import { musicListCollect, deleteMusiclist } from '../../store/musicSlice';
import { useInteraction } from '../../utils/useInteraction';
import collectEnshrine from '../../assets/images/collect_enshrine.png';
import delIcon from '../../assets/images/delete.svg';
import delHeart from '../../assets/images/del_heart.svg';
import addHeart from '../../assets/images/add_heart.svg';
import MusicItem from './componets/MusicItem';
import './index.less';

interface MusicListProps {
  deviceType?: string;
  listNum?: number;
  updataMusic?: any;
}

const MusicList: React.FC<MusicListProps> = ({
  deviceType = 'mobile',
  listNum = 0,
  updataMusic = {},
}) => {
  const dispatch = useDispatch<AppDispatch>();
  const navigate = useNavigate();
  const musicList = useSelector((state: RootState) => state.music.musicList);

  const [musicId, setMusicId] = useState<number>(1);
  const [isShowMenu, setIsShowMenu] = useState(false);
  const [menuPos, setMenuPos] = useState({ left: 0, top: 0 });
  const [musicCollect, setMusicCollect] = useState<boolean>(false);
  const [musicMask, setMusicMask] = useState<boolean>(false);
  const refMenu = useRef<HTMLDivElement>(null);
  const clickTimer = useRef(null);
  const musicListRef = useRef<any>(null);
  const DOUBLE_TAP_THRESHOLD = 300; // 双击超时时间间隔

  useEffect(() => {
    if (musicList) {
      musicListRef.current = musicList;
    }
  }, [musicList]);

  // 容器交互
  const listRef = useInteraction({
    handlers: {
      onScroll: (e: any) => scrollMusicList(e),
      onSwipe: (e: any) => swipeMusicList(e),
    },
    configs: {
      enableScroll: true,
      enableSwipe: true,
      speed: 70,
    },
  });

  // 滚动
  const scrollMusicList = (e: any): void => {
    const childElement = e.target;
    const parentHtml = childElement.closest('.music_list');
    const delta = e.offsetY;
    if (e.source !== 'mouse') {
      const scrollStep = Math.abs(delta);
      parentHtml.scrollTo({
        top: parentHtml.scrollTop + (delta >= 0 ? -scrollStep : scrollStep),
      });
    } else {
      const scrollStep = 100;
      parentHtml.scrollTo({
        top: parentHtml.scrollTop + (delta >= 0 ? scrollStep : -scrollStep),
        behavior: 'smooth',
      });
    }
  };

  // 滑动
  const swipeMusicList = (e: any): void => {
    if (window.innerWidth < 1300) {
      const childElement = e.target;
      const parentHtml = childElement.closest('.music_list');
      const height = parentHtml.getBoundingClientRect().height;
      parentHtml.scrollTo({
        top: parentHtml.scrollTop + (e.velocityY >= 0 ? -height + 60 : height - 60),
        behavior: 'smooth',
      });
    }
  };

  // 计算菜单位置
  const contextMenuLocation = (e: any): void => {
    const screenHeight = window.innerHeight;
    const menuWidth = refMenu.current?.offsetWidth || 0;
    const menuHeight = refMenu.current?.offsetHeight || 0;
    let left = e.clientX;
    let top = e.clientY;
    if (top + menuHeight > screenHeight) {
      top = screenHeight - menuHeight;
    }
    setMenuPos({ left: left - menuWidth, top });
  };

  // 收藏
  const handleCollect = (): void => {
    if (musicId) {
      const musicIndex = musicList.findIndex((item) => item.id === musicId);
      const musicItem: any = musicList.find((item) => item.id === musicId);
      if (musicIndex >= 0) {
        dispatch(musicListCollect({ index: musicIndex, collect: !musicItem.isCollect }));
      }
      setIsShowMenu(false);
      setMusicMask(false);
    }
  };

  // 删除
  const deleteMusic = (): void => {
    if (musicId) {
      const musicIndex = musicList.findIndex((item) => item.id === musicId);
      if (musicIndex >= 0) {
        dispatch(deleteMusiclist(musicList[musicIndex].id));
      }
      sessionStorage.setItem('musicList', JSON.stringify(musicList));
      setIsShowMenu(false);
      setMusicMask(false);
    }
  };

  const handleClick = (id: number): void => {
    if (clickTimer.current) {
      clearTimeout(clickTimer.current); // 第二次点击，清除单击逻辑
      clickTimer.current = null;
      handleItemDoubleClick(id); // 执行双击逻辑
    } else {
      clickTimer.current = setTimeout(() => {
        if (!isShowMenu) {
          handleItemClick(id); // 300ms 后没再点，就执行单击逻辑
        }
        clickTimer.current = null;
      }, DOUBLE_TAP_THRESHOLD) as any;
    }
  };

  // 交互事件
  const handleItemClick = (id: number): void => {
    setMusicId(id);
    navigate(`/musicListDetail?isPlay=pause&musicId=${id}`);
  };

  const handleItemDoubleClick = (id: number): void => {
    setMusicId(id);
    navigate(`/musicListDetail?isPlay=play&musicId=${id}`);
  };

  const handleItemContextMenu = (e: any, id: number): void => {
    e.preventDefault();
    setMusicId(id);
    const musicItem = musicListRef.current.find((item) => item.id === id);
    setMusicCollect(!!musicItem?.isCollect);
    contextMenuLocation(e);
    setMusicMask(true);
    setIsShowMenu(true);
  };

  document.addEventListener('click', (event): void => {
    const childElement = event.target as HTMLElement;
    const parentHtml = childElement.closest('.music_list');
    if (!parentHtml) {
      setIsShowMenu(false);
      setMusicMask(false);
    }
  });

  return (
    <div className='mu-list'>
      {musicMask && (
        <div className='music-collect-mask' onClick={(): void => setMusicCollect(false)} />
      )}
      <div
        className={[
          'music_list',
          deviceType === 'mobile' ? 'mobile_music_list' : 'pc_music_list',
        ].join(' ')}
        ref={listRef as React.RefObject<HTMLDivElement>}
      >
        {musicList.map((item) => (
          <MusicItem
            key={item.id}
            item={item}
            onClick={(): void => handleClick(item.id)}
            onDoubleClick={(): void => handleClick(item.id)}
            onContextMenu={(e): void => handleItemContextMenu(e, item.id)}
          />
        ))}
      </div>

      <div
        ref={refMenu}
        className='contextMenu'
        style={{
          visibility: isShowMenu ? 'visible' : 'hidden',
          position: 'fixed',
          left: menuPos.left,
          top: menuPos.top,
          zIndex: 1000,
        }}
      >
        <div onClick={handleCollect}>
          <img src={musicCollect ? delHeart : addHeart} alt='' />
          {musicCollect && <img src={collectEnshrine} alt='' />}
          <span>{musicCollect ? '移除收藏' : '收藏'}</span>
        </div>
        <div onClick={deleteMusic}>
          <img src={delIcon} alt='' />
          <span>删除</span>
        </div>
      </div>
    </div>
  );
};

export default MusicList;